package com.example.demo.service.impl;

import com.example.demo.entity.Image;
import com.example.demo.exception.BusinessException;
import com.example.demo.exception.ErrorCode;
import com.example.demo.mapper.ImageMapper;
import com.example.demo.service.ImageService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class ImageServiceImpl implements ImageService {

    @Autowired
    private ImageMapper imageMapper;

    @Override
    public List<Image> uploadImages(Integer imageClassId, MultipartFile[] files) {
        List<Image> images = new ArrayList<>();
        
        // 创建上传目录
        String uploadDir = System.getProperty("user.dir") + File.separator + "uploads" + File.separator;
        File dir = new File(uploadDir);
        if (!dir.exists()) {
            if (!dir.mkdirs()) {
                throw new BusinessException(ErrorCode.IMAGE_UPLOAD_FAILED, "Failed to create upload directory");
            }
        }

        for (MultipartFile file : files) {
            try {
                // 验证文件大小 (最大5MB)
                if (file.getSize() > 5 * 1024 * 1024) {
                    throw new BusinessException(ErrorCode.IMAGE_UPLOAD_FAILED, "File size exceeds 5MB limit");
                }
                
                // 验证文件类型
                String originalFilename = file.getOriginalFilename();
                if (originalFilename == null) {
                    throw new BusinessException(ErrorCode.IMAGE_UPLOAD_FAILED, "Invalid file name");
                }
                
                String extension = "";
                if (originalFilename.lastIndexOf(".") >= 0) {
                    extension = originalFilename.substring(originalFilename.lastIndexOf("."));
                }
                if (!extension.matches("(?i)\\.(jpg|jpeg|png|gif)")) {
                    throw new BusinessException(ErrorCode.IMAGE_UPLOAD_FAILED, "Only JPG, PNG, GIF images are allowed");
                }
                
                // 使用原始文件名并确保唯一性
                String baseName = originalFilename.substring(0, originalFilename.lastIndexOf("."));
                String newFilename = generateUniqueFilename(baseName, extension);
                
                // 保存文件
                String filePath = uploadDir + newFilename;
                File destFile = new File(filePath);
                try {
                    file.transferTo(destFile);
                } catch (IOException e) {
                    // 删除部分上传的文件
                    if (destFile.exists()) {
                        destFile.delete();
                    }
                    throw e;
                }
                
                // 创建Image对象
                Image image = new Image();
                image.setImage_class_id(imageClassId);
                image.setName(newFilename);
                image.setPath(filePath);
                image.setUrl("/uploads/" + newFilename);
                image.setCreate_time(new Date());
                image.setUpdate_time(new Date());
                
                // 插入数据库
                imageMapper.insert(image);
                images.add(image);
                
                log.info("Image uploaded successfully: {}", filePath);
            } catch (IOException e) {
                log.error("Failed to upload image: {}", e.getMessage());
                throw new BusinessException(ErrorCode.IMAGE_UPLOAD_FAILED, "Failed to upload image");
            }
        }
        
        return images;
    }

    @Override
    public boolean updateImageName(Integer id, String name) {
        log.info("Updating image name: id={}, new_name={}", id, name);
        if (name == null || name.trim().isEmpty()) {
            throw new BusinessException(ErrorCode.INVALID_PARAMETER, "Image name cannot be empty");
        }
        
        int result = imageMapper.updateImageName(id, name);
        if (result > 0) {
            log.info("Image name updated successfully: id={}", id);
            return true;
        }
        log.warn("Failed to update image name: id={}", id);
        throw new BusinessException(ErrorCode.IMAGE_NOT_FOUND, "Image id not found");
    }

    private String generateUniqueFilename(String baseName, String extension) {
        String filename = baseName + extension;
        int count = 0;
        
        // 检查文件名是否已存在，如果存在则添加随机数
        while (imageMapper.countByFilename(filename) > 0) {
            int randomNum = (int)(Math.random() * 9000) + 1000; // 生成4位随机数
            filename = baseName + "_" + randomNum + extension;
            count++;
            
            // 防止无限循环
            if (count > 10) {
                throw new BusinessException(ErrorCode.IMAGE_UPLOAD_FAILED, 
                    "Failed to generate unique filename after 10 attempts");
            }
        }
        return filename;
    }

    @Override
    public boolean deleteImages(List<Integer> ids) {
        log.info("Deleting images: ids={}", ids);
        if (ids == null || ids.isEmpty()) {
            throw new BusinessException(ErrorCode.INVALID_PARAMETER, "Image ids cannot be empty");
        }
        
        // Get image paths before deletion
        List<String> filePaths = imageMapper.getImagePathsByIds(ids);
        
        // Delete database records
        int result = imageMapper.deleteImagesByIds(ids);
        if (result > 0) {
            // Delete physical files
            for (String path : filePaths) {
                File file = new File(path);
                if (file.exists()) {
                    if (!file.delete()) {
                        log.warn("Failed to delete image file: {}", path);
                    }
                }
            }
            log.info("Images deleted successfully: count={}", result);
            return true;
        }
        log.warn("Failed to delete images: ids={}", ids);
        throw new BusinessException(ErrorCode.IMAGE_NOT_FOUND, "No images found with given ids");
    }
}
